package com.spring.component.rabbitmq.config;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.spring.component.utils.CollectionUtil;

/**
 * 自定义rabbitmq配置
 * 
 * @author liushihua
 * @since 2018年04月10日
 */
public class RabbitConfig {

  protected final Logger log = LoggerFactory.getLogger(this.getClass());

  public CachingConnectionFactory instanceConnectionFactory(String host, int port, String username,
      String password, String virtualHost) {
    CachingConnectionFactory factory = new CachingConnectionFactory();
    factory.setHost(host);
    factory.setPort(port);
    factory.setUsername(username);
    factory.setPassword(password);
    if (CollectionUtil.isNotBlank(virtualHost)) {
      factory.setVirtualHost(virtualHost);
    }
    return factory;
  }

  public RabbitTemplate instanceRabbitTemplate(ConnectionFactory connectionFactory) {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    // 为RabbitTemplate指定发送消息是的转换器
    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
    return rabbitTemplate;
  }

  /**
   * 配置RabbitListenerContainer的工厂类，可配置在@RabbitListener注解中的containerFactory属性
   * 
   * @param connectionFactory
   * @return
   */
  public SimpleRabbitListenerContainerFactory instanceFactory(ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    // 指定了我们接受消息的时候，以 JSON 传输的消息可以转换成对应的类型传入到方法中
    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    // 设置为手动应答
    // factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
    // 为每个listener配置并发的消费者个数的。
    // factory.setConcurrentConsumers(5);
    // 最大个数
    // factory.setMaxConcurrentConsumers(10);
    return factory;
  }

  /**
   * 配置rabbitTemplate的交换机，该模板默认发送消息到TOPIC.EXCHANGE交换机
   * 
   * @param connectionFactory
   * @throws IOException
   * @throws TimeoutException
   */
  public void topicExchangeDeclare(CachingConnectionFactory connectionFactory)
      throws IOException, TimeoutException {
    Connection connection = connectionFactory.getRabbitConnectionFactory().newConnection();
    Channel channel = connection.createChannel();
    // 交换机名称，交换机类型，是否持久化
    channel.exchangeDeclare("TOPIC.EXCHANGE", "topic", true);
  }
}
